Adds 'memory_sharing' option to domain config scripts. It passes domain id to
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 17 Dec 2009 06:27:57 +0000 (06:27 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 17 Dec 2009 06:27:57 +0000 (06:27 +0000)
the tapdisk2 process if sharing is enabled (tapdisk2 is not normally aware what
domain it is working for).

Signed-off-by: Grzegorz Milos <Grzegorz.Milos@citrix.com>
tools/blktap2/drivers/tapdisk2.c
tools/examples/xmexample.hvm
tools/memshr/interface.c
tools/memshr/memshr.h
tools/python/xen/lowlevel/xc/xc.c
tools/python/xen/xend/XendConfig.py
tools/python/xen/xend/image.py
tools/python/xen/xend/server/BlktapController.py
tools/python/xen/xm/create.py

index 015e8a39214e2a19aa04f4a761c6b748f2467408..a7d4dfb4c2981be259276573302abf18b7cf8d63 100644 (file)
@@ -34,6 +34,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/ioctl.h>
+#include <memshr.h>
 
 #include "tapdisk.h"
 #include "blktap2.h"
@@ -411,13 +412,17 @@ main(int argc, char *argv[])
 
        params = NULL;
 
-       while ((c = getopt(argc, argv, "n:h")) != -1) {
+       while ((c = getopt(argc, argv, "n:s:h")) != -1) {
                switch (c) {
                case 'n':
                        params = optarg;
                        break;
                case 'h':
                        usage(argv[0], 0);
+            break;
+        case 's':
+            memshr_set_domid(atoi(optarg));
+            break;
                default:
                        usage(argv[0], EINVAL);
                }
index 09edda6aacb317dcec81c90ab9cd1ebf0d43577c..5ff83f7bac204fd5a7e6719dfb5f22b4386e82c2 100644 (file)
@@ -25,6 +25,10 @@ memory = 128
 # Should be at least 2KB per MB of domain memory, plus a few MB per vcpu.
 # shadow_memory = 8
 
+# Whether to transparently share this domain's memory with other domains.
+# default = 0
+# memory_sharing = 0
+
 # A name for your domain. All domains must have different names.
 name = "ExampleHVMDomain"
 
index 9ab20c213c3a57f3cf7bd984d9bf63be90c71f7f..2c2f45423b9e94c3235e607b8119db0e88c16c7e 100644 (file)
 #include "memshr-priv.h"
 #include "shm.h"
 
+typedef struct {
+    int     enabled;
+    domid_t domid;
+} memshr_vbd_info_t;
+
+memshr_vbd_info_t vbd_info = {0, DOMID_INVALID};
 
 typedef struct {
     struct shared_memshr_info *shared_info;
@@ -32,6 +38,11 @@ private_memshr_info_t memshr;
 
 #define SHARED_INFO  (memshr.shared_info)
 
+void memshr_set_domid(int domid)
+{
+    vbd_info.domid = domid;
+}
+
 void memshr_daemon_initialize(void)
 {
     void *shm_base_addr;
@@ -88,5 +99,10 @@ void memshr_vbd_initialize(void)
         DPRINTF("Failed to open blockshr_hash.\n");
         return;
     }
+
+    if(vbd_info.domid == DOMID_INVALID)
+        return;
+
+    vbd_info.enabled = 1;
 }
 
index 412ddb1a4230ecf0aa8ce59d9a63effec8c75680..351323715c182b479a60b3ca073258b0fe057dc1 100644 (file)
@@ -23,6 +23,7 @@
 
 typedef uint64_t xen_mfn_t;
 
+extern void memshr_set_domid(int domid);
 extern void memshr_daemon_initialize(void);
 extern void memshr_vbd_initialize(void);
 
index c4e8840016bfcfdd3234be285dfaa223b8baa273..8a9537e9c4aec5adc36ce6294aaa3cd9131b537c 100644 (file)
@@ -1658,6 +1658,22 @@ static PyObject *pyxc_tmem_shared_auth(XcObject *self,
     return zero;
 }
 
+static PyObject *pyxc_dom_set_memshr(XcObject *self, PyObject *args)
+{
+    uint32_t dom;
+    int enable;
+
+    if (!PyArg_ParseTuple(args, "ii", &dom, &enable))
+        return NULL;
+
+    if (xc_memshr_control(self->xc_handle, dom, enable) != 0)
+        return pyxc_error_to_exception();
+    
+    Py_INCREF(zero);
+    return zero;
+}
+
+
 static PyMethodDef pyxc_methods[] = {
     { "handle",
       (PyCFunction)pyxc_handle,
@@ -2162,6 +2178,14 @@ static PyMethodDef pyxc_methods[] = {
       " auth [int]: 0|1 .\n"
       "Returns: [int] 0 on success; exception on error.\n" },
 
+    { "dom_set_memshr", 
+      (PyCFunction)pyxc_dom_set_memshr,
+      METH_VARARGS, "\n"
+      "Enable/disable memory sharing for the domain.\n"
+      " dom     [int]:        Domain identifier.\n"
+      " enable  [int,0|1]:    Disable or enable?\n"
+      "Returns: [int] 0 on success; -1 on error.\n" },
+
     { NULL, NULL, 0, NULL }
 };
 
index 7869611e87e5814952e06e24206e3ee8f2712548..150aacdcaf8146d6f029b6d7cdd721766ba7cdad 100644 (file)
@@ -230,6 +230,7 @@ XENAPI_CFG_TYPES = {
     'suppress_spurious_page_faults': bool0,
     's3_integrity' : int,
     'superpages' : int,
+    'memory_sharing': int,
 }
 
 # List of legacy configuration keys that have no equivalent in the
@@ -328,7 +329,7 @@ class XendConfig(dict):
         
         dict.__init__(self)
         self.update(self._defaults())
-
+        
         if filename:
             try:
                 sxp_obj = sxp.parse(open(filename,'r'))
@@ -390,6 +391,7 @@ class XendConfig(dict):
             'shadow_memory': 0,
             'memory_static_max': 0,
             'memory_dynamic_max': 0,
+            'memory_sharing': 0,
             'devices': {},
             'on_xend_start': 'ignore',
             'on_xend_stop': 'ignore',
@@ -441,6 +443,12 @@ class XendConfig(dict):
         if not self["memory_static_max"] > 0:
             raise XendConfigError("memory_static_max must be greater " \
                                   "than zero")
+        if self["memory_sharing"] and not self.is_hvm():
+            raise XendConfigError("memory_sharing can only be enabled " \
+                                  "for HVM domains")
+        if self["memory_sharing"] and not self.is_hap():
+            raise XendConfigError("memory_sharing can only be enabled " \
+                                  "for HAP enabled boxes")
 
     def _actions_sanity_check(self):
         for event in ['shutdown', 'reboot', 'crash']:
@@ -2150,6 +2158,10 @@ class XendConfig(dict):
         val = sxp.child_value(image_sxp, 'superpages')
         if val is not None:
             self['superpages'] = val
+        
+        val = sxp.child_value(image_sxp, 'memory_sharing')
+        if val is not None:
+            self['memory_sharing'] = val
 
         for key in XENAPI_PLATFORM_CFG_TYPES.keys():
             val = sxp.child_value(image_sxp, key, None)
index 45d7a0815ac2d795c5b33ce45b26f4be2f4d37cc..00f5b86d1fe6685ba4fbf8fbbf63f4f130c5f8fc 100644 (file)
@@ -84,6 +84,7 @@ class ImageHandler:
 
     ostype = None
     superpages = 0
+    memory_sharing = 0
 
     def __init__(self, vm, vmConfig):
         self.vm = vm
@@ -820,6 +821,8 @@ class HVMImageHandler(ImageHandler):
         self.apic = int(vmConfig['platform'].get('apic', 0))
         self.acpi = int(vmConfig['platform'].get('acpi', 0))
         self.guest_os_type = vmConfig['platform'].get('guest_os_type')
+        self.memory_sharing = int(vmConfig['memory_sharing'])
+        xc.dom_set_memshr(self.vm.getDomid(), self.memory_sharing)
 
 
     # Return a list of cmd line args to the device models based on the
index 572b7cbbfe8656d84b29842ca490eb07b343c321..f75e14dcc3d40d72cf281f5fdcc0c4ea476d21f5 100644 (file)
@@ -198,7 +198,10 @@ class Blktap2Controller(BlktapController):
                     self.deviceClass = 'tap2'
                     return devid
 
-        cmd = [ TAPDISK_BINARY, '-n', '%s:%s' % (params, file) ]
+        if self.vm.image.memory_sharing:
+            cmd = [ TAPDISK_BINARY, '-n', '%s:%s' % (params, file), '-s', '%d' % self.vm.getDomid() ]
+        else:
+            cmd = [ TAPDISK_BINARY, '-n', '%s:%s' % (params, file) ]
         (rc,stdout,stderr) = doexec(cmd)
 
         if rc != 0:
index c252acf7fbcaf6a1de7cd0ebd3eb026ce5056405..fcd2f211f5d6fda8299ee2d655d7d91c121b550b 100644 (file)
@@ -196,6 +196,10 @@ gopts.var('shadow_memory', val='MEMORY',
           fn=set_int, default=0,
           use="Domain shadow memory in MB.")
 
+gopts.var('memory_sharing', val='no|yes',
+          fn=set_bool, default=0,
+          use="Should memory be shared?")
+
 gopts.var('cpu', val='CPU',
           fn=set_int, default=None,
           use="CPU to run the VCPU0 on.")
@@ -1058,7 +1062,8 @@ def configure_hvm(config_image, vals):
              'usb', 'usbdevice',
              'vcpus', 'vnc', 'vncconsole', 'vncdisplay', 'vnclisten',
              'vncunused', 'viridian', 'vpt_align',
-             'xauthority', 'xen_extended_power_mgmt', 'xen_platform_pci' ]
+             'xauthority', 'xen_extended_power_mgmt', 'xen_platform_pci',
+             'memory_sharing' ]
 
     for a in args:
         if a in vals.__dict__ and vals.__dict__[a] is not None: